﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Collections.Generic;
using System.ComponentModel;
using RiaCrm.Infrastructure;
using System.Linq;
using Acando.Dynamics.CRM.Silverlight.Library.MetaSdk;
using Acando.Dynamics.CRM.Silverlight.Library.Interfaces;
using System.Collections.ObjectModel;

namespace RiaCrm.Searching
{
    public class Condition 
    {
        public String Name{get; set;}
    }

    public class ColumnsDefinition
    {
        public String Header{get; set;}
        public String AttributeName { get; set; }
        public AttributeMetadata attMeta { get; set; }
        public Boolean isPlaceHolder { get; set; }
    }

    public class SearchingViewModel : INotifyPropertyChanged
    {
        public ColumnsDefinition SelectedItem { get; set; } // mit twoWayBinding and die View schrauben
        public ICommand searchCommand { get; private set; }
        public String SearchBy { get; set; }
        public String SearchColumn { get; set; }
        private IEventAggregator _eventAggregator;
        private List<Condition> _conditionOptions;
        public ObservableCollection<ColumnsDefinition> Columns  {get; set; }
        private IMetaDataLayer _metaDataLayer;

        # region Properties

        //private ObservableCollection<ColumnsDefinition> Columns
        //{
        //    set
        //    {
        //        this._columns = value;
        //        this.OnPropertyChanged("Columns");
        //    }

        //    get
        //    {
        //        return this._columns;
        //    }
        //}

        public List<Condition> ConditionOptions
        {
            set
            {
                this._conditionOptions = value;
                this.OnPropertyChanged( "ConditionOptions" );
            }
            get
            {
                return this._conditionOptions;
            }
        }

        # endregion 

        /* Constructor */
        public SearchingViewModel(IEventAggregator eventAggregator, IMetaDataLayer metadatalayer)
        {
            this._eventAggregator = eventAggregator;
            this._metaDataLayer = metadatalayer;
            this._eventAggregator.GetEvent<ContextLoaded>().Subscribe(OnContextLoaded);
            this.Columns = new ObservableCollection<ColumnsDefinition>();

            this.searchCommand = new DelegateCommand<string>(OnSearchCommand);

            this.ConditionOptions = new List<Condition>() {
                                        new Condition() { Name = "Startswith"},
                                        new Condition() { Name = "Endswith"},
                                        new Condition() { Name = "Contains"}
                                    };
            // testing
            this.SearchBy = "Enter some text.......";
        }

        public void OnContextLoaded(PayLoadContext payload)
        {
            this.Columns.Clear();

            foreach (var c in payload.Columns)
            {
                
                this.Columns.Add(new ColumnsDefinition() { AttributeName = c });
            }
            
            var attDict = payload.MetaData.GetAttributesDict();

            foreach (var column in this.Columns)
            {
                if (attDict.ContainsKey(column.AttributeName))
                {
                    column.attMeta = attDict[column.AttributeName];
                    column.Header = column.attMeta.DisplayName.UserLocLabel.Label;
                }

                else // Column belongs to a referenced entity --> additional metaDataLoading is needed
                {
                    column.isPlaceHolder = true;
                    this._metaDataLayer.LoadMetaDataOfReferencedEntity(column.AttributeName, payload.MetaData, LoadMetaDataCallback);
                    
                }


            }
        }

        public void OnSearchCommand(string searchString)
        {
            this._eventAggregator.GetEvent<SearchEvent>().Publish( this.SearchBy );
        }

        private void LoadMetaDataCallback(EntityMetadata metaDataObj)
        {
            foreach (var column in this.Columns.Where(c => c.isPlaceHolder))
            {
                String PostfixName = column.AttributeName.Split(new char[] { '.' })[1];
                
                if (metaDataObj.GetAttributesDict().ContainsKey(PostfixName))
                {
                    column.attMeta = metaDataObj.GetAttributeMetadata(PostfixName);
                    column.Header = column.attMeta.DisplayName.UserLocLabel.Label;
                    column.isPlaceHolder = false;

                    return;
                }
            }

            throw new Exception("Could not find Placeholder ");
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        # endregion
    }
}
